// @ts-nocheck js改造

/**
 * 重写orderBy方法
 * 重写排序规则
 * 将英文放在中文前
 * 将sortType移至handleSort方法处理
 * https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
 * https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#casefirst
 */

import {
  arrayEach,
  toArray,
  map,
  isArray,
  isFunction,
  isPlainObject,
  isUndefined,
  isNull,
  isString,
  eqNull,
  get,
  property,
  toValueString,
  isEqual,
  toNumber
} from 'xe-utils'

// 外部
import { ignoreStartAsterisk, isNumeric } from '@/utils'

const ORDER_PROP_ASC = 'asc'
const ORDER_PROP_DESC = 'desc'
const AUTO = 'auto'
const NUMBER = 'number'
// const STRING = 'string';
const NUMBER_RECURSION = 'number:recursion'
const isChinese = (str) => /^[\u4e00-\u9fa5]+$/.test(str)
const isEnglish = (str) => /^[A-Za-z]+$/.test(str)

function isEmptyStr(str) {
  return str === ''
}

// 默认混合排序 undefined < null < '' < 纯数字 < 符号 < 数字开头混合 < 英文 < 中文
// 纯数字使用数字大小排序 数字带字符使用 字符串排序
// 默认字符串排序： 符号 < 数字(仅按位比较) < 英文 < 中文
// sortType为number时字符串排序: 数字(按大小比较) < 符号 < 英文 < 中文
// 为保证稳定,保留重复类型检查
function handleSort(v1, v2, sortType?) {
  // console.count('handleSort');
  // 减少相同长项的比较 提升5-10ms左右
  if (v1 === v2) {
    return 0
  }
  if (sortType !== NUMBER_RECURSION) {
    if (isUndefined(v1)) {
      return -1
    }

    if (isNull(v1)) {
      return isUndefined(v2) ? 1 : -1
    }

    if (isEmptyStr(v1)) {
      return isNull(v2) || isUndefined(v2) ? 1 : -1
    }

    if (!sortType || sortType === AUTO || sortType === NUMBER) {
      const isNumericV1 = isNumeric(v1)
      const isNumericV2 = isNumeric(v2)
      if (isNumericV1 && isNumericV2) {
        return v1 - v2
      } else if (isNumericV1 && !isNumericV2) {
        if (!isUndefined(v2) && !isNull(v2) && !isEmptyStr(v2)) {
          return -1
        } else {
          return 1
        }
      } else if (!isNumericV1 && isNumericV2) {
        return 1
      }
    }
    if (!isString(v1)) {
      v1 = toValueString(v1)
    }
    if (!isString(v2)) {
      v2 = toValueString(v2)
    }
  }

  // 处理数值类型排序
  if (sortType === NUMBER || sortType === NUMBER_RECURSION) {
    const sortNumber = handleSortNumber(v1, v2)
    if (sortNumber) {
      if (isArray(sortNumber)) {
        const [v1NonNumberSector, v2NonNumberSector] = sortNumber
        // 数字部分大小相同,继续比较非数字部分
        v1 = v1NonNumberSector
        v2 = v2NonNumberSector
      } else {
        return sortNumber
      }
    }
  }

  // 去除开头相同字符 减少循环比较次数
  // 在处理数值后进行 避免误差
  // 180ms => 100ms
  const [v1Suffix, v2Suffix] = removeCommonPrefix(v1, v2)
  v1 = v1Suffix
  v2 = v2Suffix

  // 处理字符混合排序 英文 中文 数字
  const sortCharacter = handleSortCharacter(v1, v2, sortType)
  if (sortCharacter) {
    return sortCharacter
  }

  return v1.localeCompare(
    v2,
    'zh-Hans-CN'
    // 第三个参数会影响性能 20000条数据 50ms=>700+ms
    // 且numeric 会导致 3.5 < 3.14 < 3.50
    //  numeric ? { numeric: sortType === NUMBER } : undefined
  )
}

function removeCommonPrefix(v1, v2) {
  let i = 0
  const len = Math.min(v1.length, v2.length)
  while (i < len) {
    if (v1.charAt(i) !== v2.charAt(i)) {
      break
    }
    i++
  }
  return [v1.slice(i), v2.slice(i)]
}

function splitNumberStr(str) {
  const match = str.trim().match(/^\d+(\.\d+)?/)
  if (match) {
    const numSector = match[0]
    const nonNumberSector = str.slice(numSector.length)
    return [numSector, nonNumberSector]
  } else {
    return [null, str]
  }
}

function handleSortNumber(v1, v2) {
  const [v1NumSector, v1NonNumberSector] = splitNumberStr(v1)
  const [v2NumSector, v2NonNumberSector] = splitNumberStr(v2)
  if (v1NumSector && v2NumSector) {
    // 仅处理开头数字排序
    if (toNumber(v1NumSector) == toNumber(v2NumSector)) {
      return v1NonNumberSector == v2NonNumberSector
        ? v1NumSector.length - v2NumSector.length
        : // 去除数字部分,继续排序
          [v1NonNumberSector, v2NonNumberSector]
    }
    return v1NumSector - v2NumSector
  } else if (v1NumSector && !v2NumSector) {
    return -1
  } else if (!v1NumSector && v2NumSector) {
    return 1
  } else {
    return false
  }
}

function handleSortCharacter(v1, v2, sortType) {
  if (isString(v1) && isString(v2)) {
    let i = 0
    const len = Math.min(v1.length, v2.length)
    while (i < len) {
      const charV1 = v1.charAt(i)
      const charV2 = v2.charAt(i)
      if (charV1 && charV2) {
        if (isChinese(charV1) && isEnglish(charV2)) {
          return 1
        } else if (isEnglish(charV1) && isChinese(charV2)) {
          return -1
        }

        // 处理字符内数值排序
        if (sortType === NUMBER || sortType === NUMBER_RECURSION) {
          if (isNumeric(charV1) || isNumeric(charV2)) {
            // 从数字开始,递归处理下一次数字排序
            return handleSort(v1.slice(i), v2.slice(i), NUMBER_RECURSION)
          }
        }

        if (charV1 === charV2) {
          i++
        } else {
          // 不满足中英文条件,直接结束
          return false
        }
      }
    }
  }
}

function buildMultiOrders(name, confs, compares) {
  return function (item1, item2) {
    const v1 = item1[name]
    const v2 = item2[name]
    // v1 和 v2 有可能是数组等非字符串格式
    if (isEqual(v1, v2)) {
      return compares ? compares(item1, item2) : 0
    }
    return confs.order === ORDER_PROP_DESC
      ? handleSort(v2, v1, confs.sortType)
      : handleSort(v1, v2, confs.sortType)
  }
}

function getSortConfs(arr, list, fieldConfs, context) {
  const sortConfs = []
  fieldConfs = isArray(fieldConfs) ? fieldConfs : [fieldConfs]
  arrayEach(fieldConfs, function (handle, index) {
    if (handle) {
      let field = handle
      let order
      let sortType
      if (isArray(handle)) {
        field = handle[0]
        order = handle[1]
        sortType = handle[2]
      } else if (isPlainObject(handle)) {
        field = handle.field
        order = handle.order
        sortType = handle.sortType
      }
      sortConfs.push({
        field: field,
        order: order || ORDER_PROP_ASC,
        sortType: sortType
      })
      arrayEach(
        list,
        isFunction(field)
          ? function (item, key) {
              item[index] = field.call(context, item.data, key, arr)
            }
          : function (item) {
              item[index] = field ? get(item.data, field) : item.data
            }
      )
    }
  })
  return sortConfs
}

/**
 * 将数组进行排序
 *
 * @param {Array} arr 数组
 * @param {Function/String/Array} fieldConfs 方法或属性
 * @param {Object} context 上下文
 * @return {Array}
 */
function orderBy(arr, fieldConfs, context?) {
  console.time('orderBy')
  if (arr) {
    if (eqNull(fieldConfs)) {
      return toArray(arr).sort(handleSort)
    }
    let compares
    let list = map(arr, function (item) {
      return { data: item }
    })
    const sortConfs = getSortConfs(arr, list, fieldConfs, context)
    let len = sortConfs.length - 1
    while (len >= 0) {
      compares = buildMultiOrders(len, sortConfs[len], compares)
      len--
    }
    if (compares) {
      list = list.sort(compares)
    }
    console.timeEnd('orderBy')
    return map(list, property('data'))
  }
  return []
}

const getOrderField = (column, $table) => {
  const { sortBy } = column
  return (row) => {
    let cellValue
    if (sortBy) {
      cellValue = isFunction(sortBy) ? sortBy({ row, column }) : get(row, sortBy)
    } else {
      cellValue = $table.getCellLabel(row, column)
    }
    // const result = handleSortFormat(cellValue, sortType);
    // if (result) {
    //   return result;
    // }

    return ignoreStartAsterisk(cellValue)
  }
}

// 表格转换用 忽略null undefined NaN 空字符串 判断
// 后续处理有真值判断，且排序时转为string
// function handleSortFormat(cellValue, sortType?) {
//   if (!sortType || sortType === AUTO) {
//     // return isNumeric(cellValue) ? toNumber(cellValue) : ignoreStartAsterisk(cellValue);
//     return isNaN(cellValue) ? ignoreStartAsterisk(cellValue) : toNumber(cellValue);
//   } else if (sortType === NUMBER) {
//     return toNumber(cellValue);
//   } else if (sortType === STRING) {
//     return toValueString(cellValue);
//   }
//   console.error('不支持排序类型: ' + sortType);
//   // throw new Error('不支持排序类型: ' + sortType);
// }

/**
 * 用于表格排序自定义方法
 */
function createTableSortMethod() {
  return function ({ $table, data, sortList }) {
    const sortFields = sortList.map(({ column, order }) => [
      getOrderField(column, $table),
      order,
      column.sortType
    ])
    return orderBy(data, sortFields)
  }
}

export { orderBy, createTableSortMethod }

// const arr = [
//   '-123',
//   'a-23',
//   'aa23',
//   'aa233',
//   'aa33',
//   23,
//   '233',
//   '4',
//   '11aa',
//   'undefined',
//   undefined,
//   null,
//   'null',
//   '(T-6608) 6-6000',
//   1,
//   '**',
//   '*',
//   '',
//   ')',
//   '(',
//   '+',
//   '-',
//   '-abc',
//   '@',
//   '~',
//   '!',
//   2,
//   3,
//   '1',
//   '2',
//   '3',
//   11,
//   'a',
//   'A',
//   '11',
//   // =====================
//   'T-6008',
//   'K-6000',
//   'K-6000',
//   'TH-20L',
//   '藏青HK-3G安诺其',
//   '藏青PUD-SW',
//   '超级黑HR-W安诺其',
//   '根PUD-SD',
//   '除菌剂HS--338A',
//   '除氧酶XL',
//   '纯碱',
//   '醋酸',
//   '翠兰GW',
//   '翠蓝G安诺其',
//   '低温皂洗剂JS580',
//   '分散草S-GL亚邦',
//   '分散红FB',
//   '分散红GS吉华',
//   '分散红玉S-5BL',
//   '分散剂DS-Powder (TS)',
//   '分散金黄SE-RL',
//   '分散嫩黄SE-4GL',
//   '分散深蓝HGL',
//   '分散艳蓝2BLLM',
//   '分散紫HFRL亚邦',
//   '高浓缩高温匀染剂HS-315',
//   '硅斑去除剂',
//   '还原剥色剂CR-20i',
//   '还原靛ZBT格瑞',
//   '还原大红GG格瑞',
//   '还原大红R亚邦',
//   '还原橄榄绿B 150%',
//   '还原橄榄绿B格瑞',
//   '还原橄榄绿F玄开',
//   '还原海军蓝R四荣',
//   '还原黑BB格瑞',
//   '还原红CB格瑞',
//   '还原红F3B',
//   '还原红F3B朋昌',
//   '还原黄3RT亚邦',
//   '还原黄GCN镍科',
//   '还原黄G百隆',
//   '还原黄G亚邦',
//   '还原原560T',
//   '还原灰BG闰色素',
//   '还原炭黑(雅鑫)',
//   '还原兰RC锐料',
//   '还原蓝GCDR上海华元',
//   '还原蓝BSN锦科',
//   '还原蓝VB四菱',
//   '还原桃红R 1508格瑞',
//   '还原桃红R格瑞',
//   '还原艳橙GR格瑞',
//   '还原艳绿FFB格瑞',
//   '还原匀染剂KE',
//   '还原棕RRN百隆',
//   '还原棕3G格瑞',
//   '还原棕BR百隆',
//   '还原棕CG亚邦',
//   '还原棕G格瑞',
//   '黑PUB-SP安诺其',
//   '红3BD安诺其',
//   '红3BE安诺其',
//   '红HB-S安诺其',
//   '红玉DS安诺其',
//   '黄3RE安诺其',
//   '黄DS安诺其',
//   '黄棕JR-F安诺其',
//   '活性超级黑RW国士',
//   '活性艳F2R安诺其',
//   '亲水硅油ESN',
//   '活性黑LB-2RLW肇庆',
//   '活性翠蓝B-BGFH德士达',
//   '活性大红2GB国士',
//   '活性大红RES闰土',
//   '活性黑RC德士达',
//   '活性红3BD德士达',
//   '活性红R-3BF闰土',
//   '活性红紫RW闰土',
//   '活性黄BCT德士达',
//   '活性黄LB-4RFW肇庆',
//   '活性蓝OSW',
//   '活性金黄B-3RD德士达',
//   '活性蓝DS德士达',
//   '活性蓝GL闰土',
//   '活性嫩黄-4GL安诺其',
//   '火碱',
//   '精炼剂CS-K1',
//   '酒粕',
//   '抗静电剂TH',
//   '科华素墨LC-G',
//   '科华素深红LC-DB龙颜',
//   '蓝DS安诺其',
//   '蓝#-2GE安诺其',
//   '尿素',
//   '柠檬酸',
//   '蓬松柔软剂PSJ-406',
//   '平滑剂 HS-286E',
//   '平滑蜡乳液 AG-42',
//   '前处理精炼剂莱索尔',
//   '柔软平滑剂169-2',
//   '软片420',
//   '深红PUD-SD安诺其渗透剂204',
//   '士林粉匀染剂DD',
//   '生物酶（精练酶）DF',
//   '双氧水',
//   '铁铵保险粉',
//   '筒子纱固色剂HS-70A',
//   '无氨漂白剂',
//   '夏利灵翠兰SWF',
//   '夏利灵深红SWF-H',
//   '线状柔软剂HC-101',
//   '盐',
//   '艳蓝RV安诺其',
//   '英才优克亮红F2B',
//   '英才体藏青HSF-N',
//   '荧光休眠HSF 200%',
//   '英才体全香HSF',
//   '荧光增白剂DBT',
//   '荧光增白剂PS-D',
//   '荧光增白剂HT-315',
//   '元明粉',
//   '约克夏PT盐',
//   '皂洗剂HY-357（原液）',
//   '皂洗剂NLX',
//   '增白剂MX',
//   '增白剂DK',
//   '增白剂S号',
//   '增白剂C2-810',
//   '增白剂CBH-16B',
//   '增白剂CBH-18',
//   '增白剂DBT-R',
//   '整理剂BH-T-806',
// ];

// const arr1 = orderBy(arr, (v) => handleSortFormat(v));
// const arr2 = orderBy(arr1, (v) => handleSortFormat(v));
// console.log(arr1, arr2);
